<template>
  <div class="base-upload-container">
    <input type="file" ref="input" @change="handleChange" :multiple="multiple" :accept="accept">

    <div class="base-file-list base-file__preview" >
      <base-file-item :readonly="editNotAllow" :Source="value" :intelligent-check-now="intelligentCheckNow" v-for="file in value" :key="file.id" :file="file" @delete="deleteFile" :formEditingMode="formEditingMode" @getDeleteFiles="(value)=>{$emit('getDeleteFiles',(value))}"></base-file-item>
    </div>

    <div class="base-upload-operation" v-if="allowUpload">
      <button
        type="button"
        class="btn btn-primary base-upload-btn"
        @click="chooseFile"
        @drop.prevent="onDrop"
        @dragover.prevent="onDragover"
        @dragleave.prevent="onDragleave"
        :disabled="pending || editNotAllow"
        :id="forId"
      >
        <i class="iconfont icon-loading" v-if="pending"></i>
        <span>{{pending ? $t('common.base.uploading') : $t('common.base.clickForUploading')}}</span>
      </button>
      <button
        v-if="isOpenCamcorder && camcorderGray"
        type="button"
        class="btn btn-primary base-upload-btn flex-x mar-l-12"
        @click="chooseFile($event, true)"
        :disabled="pending"
        :id="forId"
      >
        <i class="iconfont icon-loading" v-if="pending"></i>
        <span>{{ pending ? $t('common.base.uploading') : $t('common.form.preview.attachment.camcorderBtn') }}</span>
      </button>
      <img v-if="isOpenCamcorder && camcorderGray" id="streamimage" class="camcorder-image" :src="camcorderOpenCameraUrl"/>
      <p class="base-upload-placeholder" v-if="placeholder">{{placeholder}}</p>
    </div>
    <div class="base-upload-operation mar-t-8" v-if="allowUpload">
      <p class="base-upload-placeholder base-upload-placeholder-2">{{ $t('common.form.preview.file.pla2') }}</p>
    </div>
  </div>
</template>

<script>
import Uploader from '@src/util/uploader';
import platform from '@src/platform';

const IMG_TYPE = ['png', 'bmp', 'gif', 'jpg', 'jpeg', 'tiff'];
const WATERMARK_DEFAULT_POSTION = 'bottomRight'; // 图片水印位置默认右下
import i18n from '@src/locales';
import HttpUtil from '@src/util/HttpUtil.js'
import { getRootWindow } from '@src/util/dom';

export default {
  name: 'base-upload',
  data(){
    return {
      dragover: false,
      pending: false
    }
  },
  props: {
    limit: {
      type: Number,
      default: Uploader.FILE_MAX_NUM,
    },
    displayName: {
      type: String,
      default: () => i18n.t('common.form.type.attachment'),
    },
    action: {
      type: String,
      default: '/files/upload',
    },
    field: {
      type: Object,
      default: () => ({})
    },
    actionOptions: {
      type: Object,
      default: () => ({}) // 上传文件需要的参数
    },
    actionStorage: {
      type: String,
      default: '/files/remainingStorage', // 校验容量接口
    },
    multiple: {
      type: Boolean,
      default: true
    },
    forId: {
      type: String,
      default: ''
    },
    value: {
      type: Array,
      default: () => ([])
    },
    placeholder: {
      type: String,
      default: ''
    },
    isShowOperateContent : {
      type: Boolean,
      default: true
    },
    fileType : {
      type : String,
      default: null
    },
    fileTypes: {
      type: Array,
      default: () => []
    },
    isWaterMark: { // 加上水印
      type: Boolean,
      default: false
    },
    accept: {
      type: String,
      default: ''
    },
    intelligentCheckNow: {
      type: Boolean,
      default: false
    },
    // 表单操作模式
    formEditingMode: {
      type: String,
      default: '', // create | edit
    }
  },
  computed: {
    // 是否不允许编辑
    editNotAllow() {
      return !!this.field?.disabled
    },
    // 高拍仪上传灰度
    camcorderGray() {
      const RootWindow = getRootWindow(window);
      return Boolean(RootWindow.grayAuth?.CAMCORDER);
    },
    // 是否开启高拍仪上传
    isOpenCamcorder() {
      return this.field.setting?.isOpenCamcorder;
    },
    // 高拍仪上传接口地址
    camcorderUrl() {
      return this.field.setting?.camcorderUrl;
    },
    // 高拍仪打开摄像头地址
    camcorderOpenCameraUrl() {
      return this.field.setting?.camcorderOpenCameraUrl;
    },
    allowUpload(){
      return !(this.limit && this.queue.length >= this.limit);
    },
    queue(){
      return this.value;
    },
  },
  methods: {
    chooseFile(event, isUploadByCamcorder){
      if(!this.allowUpload) return console.warn('Caused: dont chooseFile, because of this.allowUpload is false');
      if(this.pending) return platform.alert(this.$t('common.base.uploadModal.tips1'));
      if(this.value.length >= this.limit) {
        return platform.alert(this.$t('common.base.uploadModal.uploadCountTips', {count:this.limit}));
      }

      // 高拍仪上传
      if (isUploadByCamcorder) {
        return this.chooseFileByCamcorder();
      }

      this.$refs.input.value = null;
      this.$refs.input.click();
    },
    async chooseFileByCamcorder() {
      this.pending = true;
      let result = await HttpUtil.ajax(this.camcorderUrl);
      this.pending = false;
      if (result.code == 0) {
        this.handleChange({
          target: {
            files: [this.base64ToFile(result.photoBase64)]
          }
        });
      } else {
        platform.alert(`${result.message}: ${result.data}`);
      }
    },
    // 高拍仪base64转为文件对象 （注意：高拍仪返回的base64没有data:image/png;base64,这种前缀）
    base64ToFile(base64) {
      let mime = 'image/jpg';
      let bstr = atob(base64);
      let n = bstr.length;
      let u8arr = new Uint8Array(n);
    
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
      }
      const fileName = `${Date.now()}.${mime.split('/')[1]}`;
      return new File([u8arr], fileName, { type: mime });
    },
    handleChange(event){
      const files = event.target.files;
      if(!files || !files.length) return;
      
      let allFilesLength = this.value.length + files.length;

      if(allFilesLength > this.limit) {
        let message = this.$t('common.base.uploadModal.uploadCountTips', {count:this.limit});
        let max = this.limit - this.value.length;

        if(max > 0 && files.length < this.limit){
          message += `, ${this.$t('common.base.uploadModal.canUploadCountTips', {count:max})}`;
        }

        return platform.alert(message)
      }

      if(this.fileType) {
        // 需要做文件类型校验
        for (let item of files) {
          let _fileName = item.name;
          if (!_fileName.includes(Uploader.fileTypeObj[this.fileType]['fileName'])) {
            // 没有匹配到
            this.$platform.notification({
              title: this.$t('common.base.tip.uploadErrorTips'),
              message: Uploader.fileTypeObj[this.fileType]['errMsg'],
              type: 'error',
            })
            return false;
          }
        }
      }

      if(allFilesLength > this.limit) {
        return platform.alert(this.$t('common.base.uploadModal.uploadCountTips', {count:this.limit}));
      }

      this.pending = true;
      let _self = this;
      Uploader.batchUploadWithParse({files, action: this.action, actionStorage: this.actionStorage, actionOptions: this.actionOptions }).then(async (result = {}) => {
        let {success, error} = result;
        if(error && Array.isArray(error) && error.length > 0){
          let message = error.map(item => item.message).join('\n');
          // 此处不能return
          platform.alert(message)
        }

        if(success && Array.isArray(success) && success.length > 0 && this.isWaterMark){
          // 判断是否需要加水印
          for(let i = 0; i < success.length; i ++) {
            let file = success[i];
            let currExt = this.getExt(file.filename);

            let params = {};
            if(IMG_TYPE.indexOf(currExt) > -1 && !!file.url) {
              params.urls = [file.url];
              params.position = WATERMARK_DEFAULT_POSTION;
              let waterMarkResult = await _self.$http.post('/dd/file/upload/watermark/position', params);
              if(waterMarkResult.length > 0 && waterMarkResult[0].data) {
                success[i] = waterMarkResult[0].data;
              }
            }
          }
          
        }
        success.map(item=>{
          item.fileId = item.id
        })
        let value = this.value.concat(success);

        this.$emit('input', value);

      })
        .catch(err => console.error(err))
        .then(() => this.pending = false)
    },
    async deleteFile(file) {
      let index = this.value.indexOf(file);
      if(index >= 0) {
        this.value.splice(index, 1);
        this.$emit('input', this.value);
      }
    },
    // 返回小写后缀
    getExt(fileName){
      if(!fileName) return '';

      let index = fileName.lastIndexOf('.');
      if(index < 0) return '';

      return fileName.substring(index + 1).toLowerCase();
    },
    onDragover() {
      this.dragover = true
    },
    onDragleave() {
      this.dragover = false
    },
    onDrop(event) {
      this.onDragleave()
      this.handleChange({
        target: {
          files: event?.dataTransfer?.files || []
        }
      })
    }
  }
}
</script>

<style lang="scss" >
.base-upload-container {
  overflow: hidden;
  input[type='file']{
    display: none !important;
  }
}

.base-upload-container .base-upload-btn{
  display: flex;
  flex-flow: row nowrap;
  align-items: center;
  min-width: auto;
  
  span{
    color: #fff;
  }

  &.mar-l-12 {
    margin-left: 12px;
  }

  .icon-loading{
    color: #fff;
    font-size: 18px;
    width: 18px;
    height: 18px;
    text-align: center;
    line-height: 18px;
    display: block;
    margin-right: 5px;
    animation: rotating 2s linear infinite;
  }
}

.base-upload-operation{
  display: flex;
  flex-flow: row nowrap;
  align-items: center;

  .btn-primary {
    @include backgroundColorImportant();
  }

}

.base-upload-placeholder{
  width: 100%;
  color: #9a9a9a;
  margin: 0 0 0 8px;
  font-size: 14px;
  @include text-ellipsis(); 
  &-2 {
    margin: 0;
  }
}
.camcorder-image {
  width: 0 !important;
  height: 0 !important;
}
</style>